/*
 * Copyright (c) 2018-2999 九五云信息科技有限公司 All rights reserved.
 *
 * https://www.gz-yami.com/
 *
 */

package com.yami.shop.live.comment.service.impl;

import cn.binarywang.wx.miniapp.json.WxMaGsonBuilder;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Joiner;
import com.google.gson.JsonObject;
import com.yami.shop.bean.enums.LiveInterfaceType;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.response.WxServerResponse;
import com.yami.shop.common.wx.WxInterfaceUtil;
import com.yami.shop.common.wx.bean.LiveUserReqInfo;
import com.yami.shop.common.wx.bean.resp.LiveUserRespInfo;
import com.yami.shop.config.WxConfig;
import com.yami.shop.live.comment.dao.LiveUserMapper;
import com.yami.shop.live.comment.model.LiveUser;
import com.yami.shop.live.comment.param.ReturnLiveParam;
import com.yami.shop.live.comment.service.LiveLogService;
import com.yami.shop.live.comment.service.LiveUserService;
import lombok.AllArgsConstructor;
import me.chanjar.weixin.common.enums.WxType;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.json.GsonParser;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

import static javax.swing.UIManager.get;

/**
 *
 *
 * @author lhd
 * @date 2020-11-20 17:49:56
 */
@Service
@AllArgsConstructor
public class LiveUserServiceImpl extends ServiceImpl<LiveUserMapper, LiveUser> implements LiveUserService {

    private final LiveUserMapper liveUserMapper;
    private final LiveLogService liveLogService;
    private final WxInterfaceUtil wxInterfaceUtil;
    private final WxConfig wxConfig;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public ReturnLiveParam saveInfo(LiveUser liveUser) throws WxErrorException {
        LiveUser user = getOne(new LambdaQueryWrapper<LiveUser>().eq(LiveUser::getAnchorWechat, liveUser.getAnchorWechat()));
        if(Objects.nonNull(user)){
            throw new YamiShopBindException("yami.sys.user.already");
        }
        for (Integer role : liveUser.getRoleList()) {
            LiveUserReqInfo liveUserReqInfo = new LiveUserReqInfo();
            liveUserReqInfo.setUsername(liveUser.getAnchorWechat());
            liveUserReqInfo.setRole(role);
            try {
                wxConfig.getWxMaService().post(CREATE_LIVE_USER, WxMaGsonBuilder.create().toJson(liveUserReqInfo));
            }catch (WxErrorException wxException) {
                wxException.getError();
                // TODO 先不写枚举，等以后换开源api在改
                if (wxException.getError().getErrorCode() != 0) {
                    if (wxException.getError().getErrorCode() == 400001) {
                        // 微信号不合规
                        throw new YamiShopBindException("yami.live.user.check");
                    }
                    if (wxException.getError().getErrorCode() == 400002) {
//                        // 微信号需要实名认证，仅设置主播角色时可能出现
//                        throw new YamiShopBindException("yami.live.user.name.check");
                        JsonObject jsonObject = GsonParser.parse(wxException.getError().getJson());
                        ReturnLiveParam returnUser = new ReturnLiveParam();
                        returnUser.setIsRealName(0);
                        returnUser.setImg(jsonObject.get("codeurl").getAsString());
                        return returnUser;
                    }
                    if (wxException.getError().getErrorCode() == 400003) {
                        // 重复添加角色
                        throw new YamiShopBindException("yami.live.user.check2");
                    }
                    if (wxException.getError().getErrorCode() == 400004) {
                        // 用户已具有管理员角色
                        throw new YamiShopBindException("yami.live.user.check5");
                    }
                    throw new WxErrorException(WxError.fromJson(wxException.getError().getErrorMsg(), WxType.MiniApp));
                }
            }
        }
        // 1.校验今日可用次数并保存or修改商家次数记录
        liveLogService.checkNumsAndSaveLog(liveUser.getShopId(), LiveInterfaceType.ADD_LIVE_ROLE, "添加直播成员权限");
        // 获取一遍当前用户的openId再保存，用于后续更新操作
        syncLiveUser(liveUser);
        return null;
    }

    private void syncLiveUser(LiveUser liveUser) throws WxErrorException {
        Map<String, Object> map = new HashMap<>(12);
        map.put("keyword",liveUser.getAnchorWechat());
        JsonObject jsonObject = getLiveInfo(0,1,map);
        WxServerResponse serverResponse = WxServerResponse.fromJson(jsonObject.toString());
        if(serverResponse.isSuccess() && CollectionUtil.isNotEmpty(serverResponse.getList())){
            List<LiveUserRespInfo> liveUserRespInfos = serverResponse.getList();
            LiveUserRespInfo liveUserRespInfo = liveUserRespInfos.get(0);
            Date date = new Date();
            liveUser.setUpdateTime(date);
            liveUser.setCreateTime(date);
            liveUser.setUserName(StrUtil.hide(liveUser.getAnchorWechat(), 2, liveUser.getAnchorWechat().length() - 2));
            // 将数组转成字符串
            StringBuilder roleList = new StringBuilder(100);
            for (Integer role : liveUserRespInfo.getRoleList()) {
                roleList.append(role).append(StrUtil.COMMA);
            }
            if (roleList.lastIndexOf(",") == roleList.length() - 1) {
                roleList.deleteCharAt(roleList.length() - 1);
            }
            liveUser.setRoles(roleList.toString());
            liveUser.setOpenId(liveUserRespInfo.getOpenid());
            liveUser.setNickName(liveUserRespInfo.getNickname());
            liveUser.setHeadingImg(liveUserRespInfo.getHeadingimg());
            save(liveUser);
        }
    }

    @Override
    public void synchronousWxLiveUsers() throws WxErrorException {
        List<LiveUserRespInfo> liveInfos = getLiveInfos();
        if(CollectionUtil.isEmpty(liveInfos)){
            return;
        }
        Date date = new Date();
        List<LiveUser> liveUsers = list(null);
        Map<String, LiveUser> liveUserMap = liveUsers.stream().collect(Collectors.toMap(LiveUser::getOpenId, liveUserRespInfo -> liveUserRespInfo));
        List<LiveUser> updateLiveUsers = new ArrayList<>();
        for (LiveUserRespInfo liveUserRespInfo : liveInfos) {
            if(liveUserMap.containsKey(liveUserRespInfo.getOpenid())){
                LiveUser liveUser = liveUserMap.get(liveUserRespInfo.getOpenid());
                liveUser.setUpdateTime(date);
                liveUser.setOpenId(liveUserRespInfo.getOpenid());
                liveUser.setNickName(liveUserRespInfo.getNickname());
                liveUser.setHeadingImg(liveUserRespInfo.getHeadingimg());
                // 将数组转成字符串
                StringBuilder roleList = new StringBuilder(100);
                for (Integer role : liveUserRespInfo.getRoleList()) {
                    roleList.append(role).append(StrUtil.COMMA);
                }
                if (roleList.lastIndexOf(",") == roleList.length() - 1) {
                    roleList.deleteCharAt(roleList.length() - 1);
                }
                liveUser.setRoles(roleList.toString());
                updateLiveUsers.add(liveUser);
            }
        }
        if(CollectionUtil.isNotEmpty(updateLiveUsers)){
            updateBatchById(updateLiveUsers);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeAndWeChatById(Long liveUserId) throws WxErrorException {
        LiveUser liveUser = getById(liveUserId);
        int[] roles = StrUtil.splitToInt(liveUser.getRoles(), StrUtil.COMMA);
        Map<String, Object> map = new HashMap<>(5);
        map.put("username", liveUser.getAnchorWechat());
        for (int role : roles) {
            // 1.校验今日可用次数并保存or修改商家次数记录
            liveLogService.checkNumsAndSaveLog(liveUser.getShopId(), LiveInterfaceType.REMOVE_LIVE_ROLE, "删除直播成员权限");
            map.put("role", role);
            try {
                wxConfig.getWxMaService().post(DELETE_LIVE_USER, WxMaGsonBuilder.create().toJson(map));
            }catch (WxErrorException wxException) {
                log.error(wxException.getError().getErrorMsg());
                // TODO 先不写枚举，等以后换开源api在改
                if (wxException.getError().getErrorCode() != 0) {
                    if (wxException.getError().getErrorCode() == 400005) {
                        // 主播角色删除失败，该主播存在未开播的直播间
                        throw new YamiShopBindException("yami.live.user.check4");
                    }
                    throw new WxErrorException(WxError.fromJson(wxException.getError().getErrorMsg(), WxType.MiniApp));
                }
            }
//            String responseContent = wxConfig.getWxMaService().post(DELETE_LIVE_USER, WxMaGsonBuilder.create().toJson(map));
//            JsonObject jsonObject = GsonParser.parse(responseContent);
//            if (jsonObject.get("errcode").getAsInt() != 0) {
//                throw new WxErrorException(WxError.fromJson(responseContent, WxType.MiniApp));
//            }
        }
        removeById(liveUserId);
        return true;
    }


    private List<LiveUserRespInfo> getLiveInfos() throws WxErrorException {
        List<LiveUserRespInfo> results = new ArrayList<>();
        int start = 0;
        Integer limit = 30;
        Integer total = 0;
        WxServerResponse liveUserInfoResp;
        do {
            if (total != 0 && total <= start) {
                break;
            }
            JsonObject jsonObject = getLiveInfo(start, limit, null);
            liveUserInfoResp = WxServerResponse.fromJson(jsonObject.toString());
            if (liveUserInfoResp == null) {
                return null;
            }
            results.addAll(liveUserInfoResp.getList());
            total = liveUserInfoResp.getTotal();
            start = results.size();
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                log.error("InterruptedException", e);
            }
        } while (results.size() <= total);
        return results;
    }


    private JsonObject getLiveInfo(Integer start, Integer limit, Map<String, Object> map) throws WxErrorException {
        if (map == null) {
            map = new HashMap(5);
        }
        map.put("offset", start);
        map.put("role", -1);
        map.put("limit", limit);
        String responseContent = wxConfig.getWxMaService().get(GET_LIVE_USER_INFO, Joiner.on("&").withKeyValueSeparator("=").join(map));
        JsonObject jsonObject = GsonParser.parse(responseContent);
        if (jsonObject.get("errcode").getAsInt() != 0) {
            throw new WxErrorException(WxError.fromJson(responseContent, WxType.MiniApp));
        }
        return jsonObject;
    }
}
